home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 145 / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin / tools / sharp / sxwork3.lzh / サンプル応用編 / 簡易ペイント / SPAINT.C < prev    next >
Text File  |  1994-03-10  |  11KB  |  397 lines

  1. /******************************************************************************
  2.  *    spaint.c:    ペイント編集の処理関数
  3.  ******************************************************************************
  4.  *    Workroom SX-68K Sample Program Copyright 1994 SHARP
  5.  */
  6. #include <string.h>
  7. #include <sxmemory.h>        /* メモリマンを利用するときに必要    */
  8. #include <event.h>        /* イベントマンを利用するときに必要    */
  9. #include <sxgraph.h>        /* グラフ系マネージャを利用するときに必要 */
  10. #include <dialog.h>        /* ダイアログマンを利用するときに必要    */
  11. #include "spaint.h"        /* このプログラム固有のヘッダファイル    */
  12.  
  13. /******************************************************************************
  14.  *    setComData():    登録時の共通データの設定
  15.  ******************************************************************************
  16.  *    引数:    ComVal *pcv    共通変数へのポインタ
  17.  *        ComData **hcd    登録の共通データハンドル
  18.  *    注釈:
  19.  *    図形登録時の共通データ部分の設定を行う。
  20.  *    また、データを登録したハンドルの確保を行う。
  21.  */
  22. void setComData(ComVal *pcv, ComData **hcd)
  23. {
  24.     ComData **temp;
  25.  
  26.     /* 図形種別の設定 */
  27.     (*hcd)->id = pcv->drawType;
  28.     /* 描画色の設定 */
  29.     (*hcd)->color = pcv->paletFC;
  30.     /* 描画ペンサイズの設定 */
  31.     (*hcd)->penSize = pcv->penSize;
  32.     /* 描画モードの設定 */
  33.     (*hcd)->drawMode = pcv->drawMode;
  34.  
  35.     /* データを登録したハンドルの確保を行う */
  36.  
  37.     /* データが1件も登録されていないとき */
  38.     if (pcv->dataCnt == 0 && pcv->data == NULL) {
  39.         (*hcd)->next = NULL;
  40.         pcv->data = hcd;
  41.     /* すでに登録されたデータが存在するとき */
  42.     } else {
  43.         temp = pcv->data;
  44.         pcv->data = hcd;
  45.         (*hcd)->next = temp;
  46.     }
  47.  
  48.     /* 登録データ数を更新する */
  49.     pcv->dataCnt++;
  50. }
  51.  
  52. /******************************************************************************
  53.  *    checkRectPos():    レクタングルの座標チェックおよび調整
  54.  ******************************************************************************
  55.  *    引数:    Rect *prc    チェックするレクタングル座標へのポインタ
  56.  *    注釈:
  57.  *    レクタングルの各座標をpt1がレクタングルの左上角にpt2がレクタングルの右
  58.  *    下角の座標になるように調整を行う。
  59.  */
  60. void checkRectPos(Rect *prc)
  61. {
  62.     short save;
  63.  
  64.     /* topがbottomより大きいときは入れ換える */
  65.     if (prc->d.top > prc->d.bottom) {
  66.         save = prc->d.top;
  67.         prc->d.top = prc->d.bottom;
  68.         prc->d.bottom = save;
  69.     }
  70.     /* leftがrightより大きいときは入れ換える */
  71.     if (prc->d.left > prc->d.right) {
  72.         save = prc->d.left;
  73.         prc->d.left = prc->d.right;
  74.         prc->d.right = save;
  75.     }
  76. }
  77.  
  78. /******************************************************************************
  79.  *    drawGraphRgn():    ウィンドウ内部の多角形の描画
  80.  ******************************************************************************
  81.  *    引数:    ComVal *pcv    共通変数へのポインタ
  82.  *    注釈:    drawTypeが多角形のときの処理を行う。
  83.  */
  84. void drawGraphRgn(ComVal *pcv)
  85. {
  86.     int cnt = pcv->rgnCnt;
  87.  
  88.     /* 多角形の座標入力点数が0のとき */
  89.     if (cnt == 0) {
  90.         /* 始点をセーブする */
  91.         pcv->rgnPoint[cnt] = pcv->downPos;
  92.         /* ラバーバンド表示のために始点座標を設定する */
  93.         pcv->rbSize.l.l_t = pcv->rgnPoint[cnt].x_y;
  94.  
  95.         /* カウントアップ */
  96.         pcv->rgnCnt++;
  97.     /* ダブルクリックされたとき */
  98.     } else if (pcv->animFlag == 2)
  99.  
  100.         /* 多角形の登録処理を行う */
  101.         makeRgn(pcv);
  102.  
  103.     else {
  104.         /* 入力された点を設定する */
  105.         pcv->rgnPoint[cnt] = pcv->downPos;
  106.         pcv->rgnCnt++;
  107.  
  108.         /* 入力された部分の仮表示を行う */
  109.         pcv->rbSize.l.r_b = pcv->downPos.x_y;
  110.         dispRubberBand(pcv, 1);
  111.  
  112.         /* 次のラバーバンド表示のために始点座標を設定する */
  113.         pcv->rbSize.l.l_t = pcv->rgnPoint[cnt].x_y;
  114.  
  115.         /* 入力可能な最終点のとき、ダブルクリックされたものと見なす */
  116.         if (cnt == 99) {
  117.             DMError(D_CONFIRM, "これ以上の点は入力できません。\r"
  118.                        "多角形を終了します。");
  119.             /* 多角形の登録処理を行う */
  120.             makeRgn(pcv);
  121.         }
  122.     }
  123. }
  124.  
  125. /******************************************************************************
  126.  *    makeRgn():    多角形の登録
  127.  ******************************************************************************
  128.  *    引数:    ComVal *pcv    共通変数へのポインタ
  129.  *    注釈:    多角形の登録および描画処理を行う。
  130.  */
  131. void makeRgn(ComVal *pcv)
  132. {
  133.     int cnt, errCode;
  134.     ComData **hcd;
  135.  
  136.     /* 多角形の仮表示の消去を行う */
  137.     dispRubberBand(pcv, 2);
  138.  
  139.     /* ペンサイズの設定 */
  140.     GMPenSize(pcv->penSize.x_y);
  141.     GMForeColor(pcv->paletFC);
  142.  
  143.     /* データ登録用にメモリを確保する */
  144.     hcd = MMChHdlNew(sizeof(ComData));
  145.     if (hcd == NULL) {
  146.         DMError(D_CONFIRM, "メモリが不足しています。\r"
  147.                    "データの登録ができません。");
  148.         return;
  149.     }
  150.  
  151.     /* 空のリージョンを作成する */
  152.     (*hcd)->ext.rgn.hdl = GMNewRgn();
  153.     if ((*hcd)->ext.rgn.hdl == NULL) {
  154.         DMError(D_CONFIRM, "メモリが確保できません。");
  155.         return;
  156.     }
  157.     /* リージョンの記録開始 */
  158.     GMOpenRgn();
  159.     /* 多角形形の描画 */
  160.     /* 表示位置をデータの先頭に設定する */
  161.     GMMove(pcv->rgnPoint[0].x_y);
  162.     /* データを元に描画を行う */
  163.     for (cnt = 1; cnt < pcv->rgnCnt; cnt++)
  164.         GMLine(pcv->rgnPoint[cnt].x_y);
  165.     /* 始点データと結ぶ */
  166.     GMLine(pcv->rgnPoint[0].x_y);
  167.     /* リージョンの記録終了 */
  168.     errCode = GMCloseRgn((*hcd)->ext.rgn.hdl);
  169.     if (errCode < 0) {
  170.         DMError(D_CONFIRM, "メモリが不足しています。\r"
  171.                    "リージョンの記録ができません。");
  172.         return;
  173.     }
  174.  
  175.  
  176.     /* 多角形を囲むレクタングルの座標をcomDataのboundsに設定する */
  177.     (*hcd)->bounds = (*(*hcd)->ext.rgn.hdl)->bounds;
  178.     /* 多角形の点数を設定 */
  179.     (*hcd)->ext.rgn.cnt = pcv->rgnCnt;
  180.     /* リージョンデータを設定する */
  181.     memcpy((*hcd)->ext.rgn.point, pcv->rgnPoint, sizeof(Point) * MAX_RGN_CNT);
  182.  
  183.     /* 共通データの登録処理 */
  184.     setComData(pcv, hcd);
  185.  
  186.     /* 入力された多角形の描画を行う */
  187.     GMFrameRgn((*hcd)->ext.rgn.hdl);
  188.  
  189.     /* 多角形処理フラグをオフにする */
  190.     pcv->rgnCnt = 0;
  191.     /* 描画フラグをクリアする */
  192.     pcv->animFlag = 0;
  193. }
  194.  
  195. /******************************************************************************
  196.  *    drawAll():    ウィンドウ内部全体の描画
  197.  ******************************************************************************
  198.  *    引数:    ComVal *pcv    共通変数へのポインタ
  199.  */
  200. void drawAll(ComVal *pcv)
  201. {
  202.     /* dataを元に描画されたすべての図形の描画を行う */
  203.     drawNext(pcv->data);
  204. }
  205.  
  206. /******************************************************************************
  207.  *    drawNext():    現在描画されている図形をすべて描画
  208.  ******************************************************************************
  209.  *    引数:    ComData **next    描画図形データのハンドル
  210.  */
  211. void drawNext(ComData **next)
  212. {
  213.     ComData **hcd;
  214.  
  215.     /* 一番最初に描画された図形データから描画を行う */
  216.  
  217.     /* 指定図形データのハンドルがNULLならば処理終了 */
  218.     if (next == NULL)
  219.         return;
  220.  
  221.     hcd = next;
  222.     /* 1つ前のデータのハンドルを渡して図形の描画を行う */
  223.     drawNext((*hcd)->next);
  224.     /* 実際のデータの描画を行う */
  225.     drawOne(next);
  226. }
  227.  
  228. /******************************************************************************
  229.  *    drawOne():    指定された図形データの描画
  230.  ******************************************************************************
  231.  *    引数:    ComData **data    描画図形データのハンドル
  232.  */
  233. void drawOne(ComData **data)
  234. {
  235.     int id, mode;
  236.     Rect rc;
  237.     ComData **hcd;
  238.  
  239.     /* hcdにハンドルを設定する */
  240.     hcd = data;
  241.  
  242.     /* idに図形の種類を取得する */
  243.     id = (*hcd)->id;
  244.  
  245.     /* 指定図形データのペンサイズに設定する */
  246.     GMPenSize((*hcd)->penSize.x_y);
  247.     /* 指定図形データの描画色に設定する */
  248.     GMForeColor((*hcd)->color);
  249.     /* modeに指定図形データの描画モードを設定する */
  250.     mode = (*hcd)->drawMode;
  251.  
  252.     /* 図形の種類が多角形ではないとき */
  253.     if (id >= 1 && id <=4) {
  254.  
  255.         /* 描画する座標をrcに設定する */
  256.         rc = (*hcd)->bounds;
  257.  
  258.         /* 図形の種類および描画モードによって描画を行う */
  259.         drawZukei(id, mode, &rc, (*hcd)->ext.radius.x_y);
  260.     /* 多角形のとき */
  261.     } else if ((*hcd)->ext.rgn.hdl != NULL) {
  262.         /* 描画モードによって多角形の描画を行う */
  263.         if (mode == 0)
  264.             GMFrameRgn((*hcd)->ext.rgn.hdl);
  265.         else
  266.             GMFillRgn((*hcd)->ext.rgn.hdl);
  267.     }
  268. }
  269.  
  270. /******************************************************************************
  271.  *    dispRubberBand():    ラバーバンド表示処理
  272.  ******************************************************************************
  273.  *    引数:    ComVal *pcv    共通変数へのポインタ
  274.  *        int type    描画方法
  275.                 = 0: 通常のラバーバンド表示
  276.  *                = 1: ラバーバンド表示の消去のみ
  277.  *                = 2: 多角形の仮表示消去
  278.  */
  279. void dispRubberBand(ComVal *pcv, int type)
  280. {
  281.     int savPenMode;
  282.     int cnt;
  283.  
  284.     /* 処理対象外 */
  285.     if (type == 0 && (pcv->drawType == 5 && pcv->rgnCnt == 0))
  286.         return;
  287.  
  288.     else if (type == 0 && pcv->drawType != 5)
  289.         if (pcv->animFlag != 1 || !EMLStill())
  290.             return;
  291.  
  292.     /* ペンサイズの設定 */
  293.     GMPenSize(LONGWORD(1, 1));
  294.     /* 表示色を白に設定 */
  295.     GMForeColor(15);
  296.     /* ペンモードをXORに設定する */
  297.     savPenMode = GMPenMode(G_XOR);
  298.  
  299.     /* 通常のラバーバンド処理のときおよびラバーバンド消去のとき */
  300.     if (type == 0 || type == 1) {
  301.         /* 画面上にラバーバンド表示がある場合は消去する */
  302.         if (pcv->dispRbFlag || type == 1)
  303.             drawZukei(pcv->drawType, 0, &pcv->rbSize, pcv->radius.x_y);
  304.         /* 通常のラバーバンド処理のとき */
  305.         if (type == 0) {
  306.             /* ラバーバンド表示フラグをTRUEにする */
  307.             if (!pcv->dispRbFlag)
  308.                 pcv->dispRbFlag = TRUE;
  309.             /* マウスポインタの位置を取得する */
  310.             pcv->rbSize.l.r_b = EMMSLoc();
  311.             /* ラバーバンドの表示を行う */
  312.             drawZukei(pcv->drawType, 0, &pcv->rbSize, pcv->radius.x_y);
  313.         /* ラバーバンド消去のとき */
  314.         /* ラバーバンド表示フラグをFALSEにする */
  315.         } else if (pcv->dispRbFlag)
  316.             pcv->dispRbFlag = FALSE;
  317.     /* 多角形の仮表示消去のとき */
  318.     } else {
  319.         /* 表示位置をデータの先頭に設定する */
  320.         GMMove(pcv->rgnPoint[0].x_y);
  321.         /* 格納データを元に仮表示を消去する */
  322.         for (cnt = 1; cnt < pcv->rgnCnt; cnt++)
  323.             GMLine(pcv->rgnPoint[cnt].x_y);
  324.     }
  325.  
  326.     /* ペンモードを元に戻す */
  327.     GMPenMode(savPenMode);
  328.     /* 描画色を現在の描画色に設定 */
  329.     GMForeColor(pcv->paletFC);
  330.     /* ペンサイズを現在の描画色に設定 */
  331.     GMPenSize(pcv->penSize.x_y);
  332. }
  333.  
  334. /******************************************************************************
  335.  *    drawZukei():    実際の図形表示処理
  336.  ******************************************************************************
  337.  *    引数:    int type    描画図形の種類
  338.  *        int mode    描画モード
  339.  *                = 0: 枠
  340.  *                = 1: 塗りつぶし
  341.  *        Rect *prc    表示に使用する座標
  342.  *        LPoint radius    半径(ラウンドレクタングルのとき有効)
  343.  *    注釈:
  344.  *    指定の図形を指定の座標を用いて表示する。
  345.  *    リージョンについてはラバーバンド表示のときのみ対応。
  346. */
  347. void drawZukei(int type, int mode, Rect *prc, LPoint radius)
  348. {
  349.     Rect rc;
  350.  
  351.     switch (type) {
  352.     case 1:
  353.     case 5:
  354.         /* 直線の描画を行う */
  355.         GMMove(prc->l.l_t);
  356.         GMLine(prc->l.r_b);
  357.         break;
  358.     case 2:
  359.     case 3:
  360.     case 4:
  361.         /* prcのデータをrcにコピーする */
  362.         rc = *prc;
  363.         /* レクタングルの座標をチェックする */
  364.         checkRectPos(&rc);
  365.         switch (type) {
  366.         case 2:
  367.             /* 長方形の描画を行う */
  368.             if (mode == 0)
  369.                 /* 描画モードが枠のとき */
  370.                 GMFrameRect(&rc);
  371.             else
  372.                 /* 描画モードが塗りつぶしのとき */
  373.                 GMFillRect(&rc);
  374.             break;
  375.         case 3:
  376.             /* 楕円の描画を行う */
  377.             if (mode == 0)
  378.                 /* 描画モードが枠のとき */
  379.                 GMFrameOval(&rc);
  380.             else
  381.                 /* 描画モードが塗りつぶしのとき */
  382.                 GMFillOval(&rc);
  383.             break;
  384.         default:
  385.             /* 面取り長方形の描画を行う */
  386.             if (mode == 0)
  387.                 /* 描画モードが枠のとき */
  388.                 GMFrameRRect(&rc, radius);
  389.             else
  390.                 /* 描画モードが塗りつぶしのとき */
  391.                 GMFillRRect(&rc, radius);
  392.             break;
  393.         }
  394.         break;
  395.     }
  396. }
  397.